package com.njcb.ams.support.autoconfigure;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.njcb.ams.support.beanprocessor.AmsBusinessPlugScanner;
import com.njcb.ams.support.config.AmsConfigUtil;
import com.njcb.ams.support.exception.ExceptionUtil;
import com.njcb.ams.support.plug.Plug;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.StringUtils;

import com.njcb.ams.support.autoconfigure.annotation.EnableAmsManagement;
import com.njcb.ams.support.beanprocessor.AmsBusinessBeanScanner;

/**
 * @author LOONG
 */
public class AmsPackageScan implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
    /**
     * 扫描路径
     */
    public static final String SCAN_BASE_PACKAGES = "scanBasePackages";

    private ResourceLoader resourceLoader;

    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        AnnotationAttributes annotationAttrs = AnnotationAttributes.fromMap(annotationMetadata.getAnnotationAttributes(EnableAmsManagement.class.getName()));
        //自定义的 包扫描器
        DefaultListableBeanFactory registry = new DefaultListableBeanFactory();
        AmsBusinessPlugScanner metaHandle = new AmsBusinessPlugScanner(beanDefinitionRegistry, registry);
        AmsBusinessBeanScanner scanHandle = new AmsBusinessBeanScanner(beanDefinitionRegistry, registry);
        if (resourceLoader != null) {
            metaHandle.setResourceLoader(resourceLoader);
            scanHandle.setResourceLoader(resourceLoader);
        }
        List<String> basePackages = new ArrayList<>();
        assert annotationAttrs != null : "属性不能为空";
        for (String pkg : annotationAttrs.getStringArray(SCAN_BASE_PACKAGES)) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(pkg);
            }
        }
        //扫描指定路径下的接口
        Set<BeanDefinitionHolder> plugDefinitions = metaHandle.doScan(StringUtils.toStringArray(basePackages));
        //扫描指定路径下的接口
        Set<BeanDefinitionHolder> beanDefinitions = scanHandle.doScan(StringUtils.toStringArray(basePackages));

        /**
         * 将扫描到的Bean注入到容器
         */
        plugDefinitions.forEach(beanDefinitionHolder -> {
            registry.registerBeanDefinition(beanDefinitionHolder.getBeanName(), beanDefinitionHolder.getBeanDefinition());
            Object plugObj = registry.getBean(beanDefinitionHolder.getBeanName());
            if (plugObj instanceof Plug) {
                Plug plug = (Plug) plugObj;
                List<Class> annotationTypes = plug.annotationType();
                annotationTypes.forEach(cls -> {
                    AmsConfigUtil.addScanAnnotation(cls,plug);
                });
            } else {
                ExceptionUtil.throwAppException(beanDefinitionHolder.getBeanDefinition().getBeanClassName() + "未实现Plug接口");
            }
        });

        /**
         * 将扫描到的Bean注入到容器
         */
        beanDefinitions.forEach(beanDefinitionHolder -> {
            registry.registerBeanDefinition(beanDefinitionHolder.getBeanName(), beanDefinitionHolder.getBeanDefinition());
        });
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
}